package com.netty.pro.netty.groupChat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import javax.lang.model.element.VariableElement;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author xuzn
 * @ClassName: GroupChatServerHandler
 * @ProjectName netty-pro
 * @date 2020/3/15/10:06
 */
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {

  // 定义一个channel组,管理所有的channel
  // GlobalEventExecutor事件执行器,是一个单利
  private static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

  @Override
  protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
    // 获取当前的channel
    Channel channel = ctx.channel();
    channels.forEach(ch -> {
      if (ch != channel) {
        ch.writeAndFlush("[客户]" + channel.remoteAddress() + "发送消息:" + msg + "\n");
      } else {
        ch.writeAndFlush("自己发送了消息" + msg + "\n");
      }
    });
    System.out.println("[客户]" + channel.remoteAddress() + "发送消息:" + msg + "\n");
    // 加入这句话其实就是通知自己
//    ctx.writeAndFlush("[客户]"+channel.remoteAddress()+"发送消息:"+msg+"\n");
  }

  // 表示连接建立,第一个被执行
  // 将当前的channel加入到channelGroup中
  @Override
  public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
    Channel channel = ctx.channel();
    // 将客户加入聊天信息推送给其他在线客户
    /**
     * 改方法会 将channelGroup中的所有channel遍历并发送消息
     */
    channels.writeAndFlush("[客户端]" + channel.remoteAddress() + "加入聊天" + sdf.format(new Date()) + "\n");
    channels.add(channel);
  }

  // 表示断开连接会被触发
  @Override
  public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
    Channel channel = ctx.channel();
    channels.writeAndFlush(channel.remoteAddress() + "离开聊天~~\n");
    System.out.println("channelGroup的长度:" + channels.size());
  }

  // 表示channel处于活动的状态
  @Override
  public void channelActive(ChannelHandlerContext ctx) throws Exception {
    System.out.println(ctx.channel().remoteAddress() + "上线了");
  }

  // 表示channel不活跃,提示离线
  @Override
  public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    System.out.println(ctx.channel().remoteAddress() + "离线");
  }

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    ctx.close();
  }
}
